/**
 * Created by cxl on 2017/8/22.
 */

var Poker = require('./Poker');


/***
 * 获取格式化后的牌组:{"cardPoint":{"num":,"hasColor":[]}}
 * @param cards
 */
function getFormatCards(cards) {
    var formatCard = {};
    ExObject.eachKeyNum(cards, function (c, n) {
        if (n > 0) {
            var point = Poker.getPoint(c);
            var color = Poker.getColor(c);
            if (!formatCard[point]) {
                formatCard[point] = {
                    "num": 0,
                    "hasColor": []
                }
            }
            formatCard[point].num += n;
            if (formatCard[point].hasColor.indexOf(color) != -1) {
                formatCard[point].hasColor.push(color);
            }
        }
    }).bind(this);
    return formatCard;
}

/***
 * 获取牌组中最大的一张牌
 * @param cards
 * @returns {number}
 */
function getMaxCard(cards) {
    var maxCard = 0;
    ExObject.eachKeyNum(cards, function (c, n) {
        if (Poker.getPoint(c) > Poker.getPoint(maxCard)) {
            maxCard = c;
        }
    });
    return maxCard;
}

/***
 * 获取牌组中最小的一张牌
 * @param cards
 * @returns {number}
 */
function getMinCard(cards) {
    var minCard = getMaxCard(cards);
    ExObject.eachKeyNum(cards, function (c, n) {
        if (Poker.getPoint(c) < Poker.getPoint(minCard)) {
            minCard = c;
        }
    });
    return minCard;
}

/***
 * 检测是否为单张
 * @param cards
 * @returns {boolean}
 */
function checkSingle(cards) {
    if (Poker.sumCardsNum(cards) != 1) {
        return false;
    }
    return true;
}

/***
 * 检测是否为对子
 * @param cards
 * @returns {boolean}
 */
function checkPair(cards) {
    if (Poker.sumCardsNum(cards) != 2) {
        return false;
    }
    var costCards = getFormatCards(cards);
    var resp = true;
    ExObject.eachKeyNum(costCards, function (c, v) {
        if (v.num != 2) {
            resp = false;
            return false;
        }
    });
    return resp;
}

/***
 * 检测连对
 * @param cards
 * @returns {boolean}
 */
function checkPairs(cards) {
    var num = Poker.sumCardsNum(cards);

    if (num % 2 != 0) {
        return false;
    }
    if (num != 6) {
        return false;
    }

    var resp = this.checkStraight(cards, 2, 3);

    return resp;
}

/***
 * 检测是不是顺子
 * @param cards 要检测的牌组
 * @param pairsNum 单个对子有几张牌
 * @param straightNum 顺子的长度
 * @returns {boolean}
 */
function checkStraight(cards, pairsNum, straightNum) {
    var result = true;
    var formatCards = getFormatCards(cards);
    var maxCardPoint = Poker.getValue(getMaxCard(cards));

    if (maxCardPoint == 13 && formatCards[1]) {
        //如果最大的牌是K，并且牌组中有A
        for (var i = maxCardPoint; i < maxCardPoint - straightNum + 1; i--) {
            if (!formatCards[i] || formatCards[i].num != pairsNum) {
                result = false;
                break;
            }
        }
        if (result && (formatCards[1].num != pairsNum)) {//QK符合要求了 就检测A
            result = false;
        }
        return result;
    }

    for (var i = maxCardPoint; i > maxCardPoint - straightNum + 1; i--) {
        if (!formatCards[i] || formatCards[i].num != pairsNum) {
            result = false;
            break;
        }
    }
    return result;
}

/***
 * 三张牌
 * @param cards
 * @returns {boolean}
 */
function checkTriple(cards) {
    if (Poker.sumCardsNum(cards) != 3) {
        return false;
    }
    var formatCard = getFormatCards(cards);
    var resp = true;
    ExObject.eachKeyNum(formatCard, function (c, v) {
        if (v.num != 3) {
            resp = false;
            return false;
        }
    });
    return resp;
}

/***
 * 检测三带二
 * @param cards
 * @returns {boolean}
 */
function checkTripleTwo(cards) {
    if (Poker.sumCardsNum(cards) != 5) {
        return false;
    }
    var formatCard = getFormatCards(cards);
    var resp = false;
    var context = {
        'triple': 0,
        'pair': 0
    };
    ExObject.eachKeyNum(formatCard, function (c, v) {
        if (v.num == 3) {
            context.triple += 1;
        }
        if (v.num == 2) {
            context.pair += 1;
        }
    });
    if (context.triple == 1 && context.pair == 1) {
        resp = true;
    }
    return resp;
}

/***
 * 检测飞机
 * @param cards
 * @returns {boolean}
 */
function checkAirplane(cards) {
    var num = Poker.sumCardsNum(cards);
    if (num != 6) {
        return false;
    }

    var resp = checkStraight(cards, 3, 2);

    return resp;
}

/***
 * 检测顺子
 * @param cards
 * @returns {boolean}
 */
function checkRun(cards) {
    var num = Poker.sumCardsNum(cards);
    if (num < 5) {
        return false;
    }
    var resp = checkStraight(cards, 1, 5);
    return resp;
}

/***
 * 检测炸弹
 * @param cards 牌组
 * @param boomNum 几炸
 * @returns {boolean}
 */
function checkBomb(cards, boomNum) {
    var num = Poker.sumCardsNum(cards);
    var resp = false;
    if (num == boomNum) {
        var formatCard = getFormatCards(cards);
        ExObject.eachKeyNum(formatCard, function (c, v) {
            if (v.num == boomNum) {
                resp = true;
                return false;
            }
        });
    }
    return resp;
}

/**
 * 检测王炸
 * @param cards
 * @returns {boolean}
 */
function checkKingBomb(cards) {
    var num = Poker.sumCardsNum(cards);
    var resp = false;
    if (num == 4) {
        if (cards[Poker.SpecPoint.JOKER_B] == 2 && cards[Poker.SpecPoint.JOKER_S] == 2) {
            resp = true;
        }
    }
    return resp;
}

/***
 * 检测同花顺
 * @param cards
 * @returns {boolean}
 */
function checkTHS(cards) {
    var isRun = checkRun(cards);
    var sameColor = Poker.getColor(getMaxCard(cards));
    if (isRun) {
        var isTH = true;
        ExObject.eachKeyNum(cards, function (c, n) {
            if (Poker.getColor(c) != sameColor && n != 1) {
                isTH = false;
                return false;
            }
        });
        return isTH;
    } else {
        return false;
    }
}

/***
 * 比较两个牌的大小返回最大的牌
 * @param card1
 * @param card2
 * @returns {*}
 */
function compareMaxCard(card1, card2) {
    if (card1 < 100 && card2 > 100) {
        return card1;
    }
    if (card1 > 100 && card2 < 100) {
        return card2
    } else {
        return (card1 >= card2) ? card1 : card2;
    }
}

/***
 * 比较两个牌的大小返回最大的牌
 * @param card1
 * @param card2
 * @returns {*}
 */
function compareMinCard(card1, card2) {
    if (card1 < 100 && card2 > 100) {
        return card2;
    }
    if (card1 > 100 && card2 < 100) {
        return card1
    } else {
        return (card1 >= card2) ? card2 : card1;
    }
}

module.exports = {
    getFormatCards: getFormatCards,
    getMaxCard: getMaxCard,
    getMinCard: getMinCard,

    checkStraight: checkStraight,
    checkSingle: checkSingle,
    checkPair: checkPair,
    checkPairs: checkPairs,
    checkTriple: checkTriple,
    checkTripleTwo: checkTripleTwo,
    checkAirplane: checkAirplane,
    checkBomb: checkBomb,
    checkKingBomb: checkKingBomb,
    checkTHS: checkTHS,
    compareMaxCard: compareMaxCard,
    compareMinCard: compareMinCard
}